

inline 
gmm_model::gmm_model(int in_Ncent, field<std::string> in_actions)
:N_cent(in_Ncent), actions(in_actions)
{
}


inline
void
gmm_model::create_gmm_action()
{ 
  
  cout << "# clusters: " << N_cent << endl;
  
  for (uword sc = 1; sc <= 4; ++sc)
{
  
  for (uword act = 0 ; act < actions.n_rows;  ++act) {
    
    
    cout << "Calculating GMM for scenario " << sc << " action " << actions(act) << endl;
    stringstream tmp_ss4;
    tmp_ss4 << "./run1/features/train/feature_vectors_" << actions(act)<< "_d"<< sc;

    mat mat_features;
    mat_features.load( tmp_ss4.str() );
    
    
    gmm_diag gmm_model;
    gmm_model.learn(mat_features, N_cent, eucl_dist, static_subset, 20, 5, 1e-10, true);   
    
    std::stringstream tmp_ss5;
    tmp_ss5 << "./run1/gmm_models/Ng" << N_cent << "_" << actions(act) << "_d"<<sc; 
    cout << "Saving GMM in " << tmp_ss5.str() << endl;
    gmm_model.save( tmp_ss5.str() );
  }
  
}
}


inline 
void 
gmm_model::gmm_multi_action( )
{
  
  double ave_acc=0;
  //int L =25;
  int L = 13;
  
  field<mat> featuresframe_video_i; // Features for frame i are in  arow of this field
  
  uvec real_labels;
  
  cout << "Testing for GMM with " << N_cent << " centroids" << endl;
  
  field<std::string> person;
  person.load("./run1/features/multi_test/person_list_Run1.txt");
  //person.print();
  
  field<std::string> lab_person;
  lab_person.load("./run1/features/multi_test/Labperson_list_Run1.txt");
  //lab_person.print();
  
  /*
   std::stringstream tmp_ss;
      tmp_ss << single_path << train_list(q1(u));
   */
  
  //cout << "person.n_rows " << person.n_rows << endl;
  //cout << "lab_person.n_rows "  << lab_person.n_rows << endl;
  
 
   vec likelihood_actions_scenes;
   vec likelihood_label;
   
  for (uword vi = 0; vi <person.n_rows; ++vi ){ 
    
    std::stringstream tmp_ss4;
    tmp_ss4 << "./run1/features/multi_test/"<< person(vi);  // 17 for training from 18 onwards for testing	std::stringstream tmp_vec_lab;
    std::stringstream tmp_vec_lab;
    
    tmp_vec_lab << "./run1/features/multi_test/"<< lab_person(vi);  // 17 for training from 18 onwards for testing
    //cout << tmp_vec_lab.str()<< endl;
    
    featuresframe_video_i.load( tmp_ss4.str() );
    
    
    real_labels.load( tmp_vec_lab.str(), raw_ascii );
   
    
    //real_labels.t().print("real_labels");
    
    
    //conv_to< colvec >::from(x)
    int num_frames = featuresframe_video_i.n_rows;
    
    
    mat log_prob;
    log_prob.zeros(num_frames, actions.n_rows*4);   //* 4 scenerarios
    
    cout << "Doing for person " << person(vi) << endl;
    //cout << "num_frames " << num_frames << endl;
    //cout << "num_labels " << real_labels.n_elem << endl;
    
    
    for ( uword fr = 0; fr < num_frames -L +1 ; ++fr)
       {
	 //cout << fr << endl;
	 mat mat_features;
	 
	 //cout << " j = " << fr << " to  j< " << fr+L << endl ;
	 for (uword j = fr; j< fr+L; j++)
	 {
	   //cout << j << " " ;
	   mat_features	 = join_rows( mat_features, featuresframe_video_i(j) );
	   
	   
	   
	 }
	 
	 
	 //cout << endl;
	 mat likelihood_actions = get_loglikelihoods(mat_features);
	 likelihood_actions_scenes = likelihood_actions.col(0);
	 likelihood_label = likelihood_actions.col(1);
	 
	 //vec likelihood_actions = get_loglikelihoods(mat_features);
	 
	 
	 //likelihood_actions_scenes.t().print();
	 //cout << endl << "ini " << fr << " fin:" << fr + L-1 << endl;
	 log_prob.rows(fr, fr + L-1).each_row() += likelihood_actions_scenes.t();
	 
	 
	 //getchar();
	 //cout << log_prob.rows(0, fr + L + 5) << endl;
	 
	 //mat X = log_prob.submat(0,0, fr + L + 5,6);
	 //X.print();
	 //X.submat( first_row, first_col, last_row, last_col )
	 //getchar();
	 
	 
       }
       //log_prob.print();
       //cout << "Done here" << endl;
       //getchar();
       uvec est_labels(num_frames);
       
       
       
       for ( uword i = 0; i < num_frames; ++i)
       {
	 //cout << " " << i;
	 uword index;
	 double max_frame = log_prob.row(i).max(index);
	 //cout << "Log_prob_frame " << i << "= " << log_prob.row(i) << endl;
	 
	 //cout << "Max for " << log_prob.row(i) << " is " << max_frame << " pos: " << index<< endl;
	 
	 est_labels(i) = likelihood_label(index);
	 //cout << "est_labels(i) " << est_labels(i) << endl;
	 
	 
	 
	 //getchar();
	 
       }
       
       std::stringstream tmp_save_estlab;
       tmp_save_estlab<< "./run1/results/est_"<<lab_person(vi);  
       
       est_labels.save(tmp_save_estlab.str(), raw_ascii);
       
       
       std::stringstream tmp_save_real_lab;
       tmp_save_real_lab << "./run1/results/real_"<<lab_person(vi);  
       
       real_labels.save( tmp_save_real_lab.str(), raw_ascii );
       
       uvec comparing = find( est_labels == real_labels);
       double acc = comparing.n_elem;
       cout <<"performance for person "<<person(vi)<<" is "<<setprecision(2)<<fixed<<100*acc/est_labels.n_elem << " %"<<endl;
       ave_acc = ave_acc + 100*acc/est_labels.n_elem;
       //getchar();
  }
  
  cout << "Average performance is " << setprecision(2) << fixed << ave_acc/person.n_rows << " %"<<endl;

}


inline
mat
gmm_model::get_loglikelihoods(mat mat_features)
{
  //cout << "get_loglikelihoods" << endl;
  mat likelihood_actions(actions.n_rows*4,2);
  vec likelihood_actions_scenes(actions.n_rows*4); ///* 4 scenarios
  vec likelihood_label(actions.n_rows*4);
  
  int pos = 0;
  
  for (uword sc = 1; sc <= 4; ++sc)
  {
  for (uword act_tr = 0; act_tr < actions.n_rows; ++act_tr)
  {
    
    //Scaling
//     cout << "scaling" << endl;
//     std::stringstream tmp_scal;
//     tmp_scal<<  "./run1/features/train/feature_vectors_scaling_field" << actions(act_tr)<< "_d"<< sc;
//     field<rowvec> scaling;
//     scaling.load( tmp_scal.str() );
//     rowvec mean_dim = scaling(0);
//     rowvec std_dim  = scaling(1);
//     mat_features.each_col()-=mean_dim.t() ;
//     mat_features.each_col()/=std_dim.t() ;
    //end scaling
  
  
    gmm_diag gmm_model;
    std::stringstream tmp_ss5;
    tmp_ss5 << "./run1/gmm_models/Ng" << N_cent << "_" << actions(act_tr) << "_d"<<sc; 
    //cout << tmp_ss5.str() << endl;
    gmm_model.load( tmp_ss5.str());
    
    likelihood_actions_scenes (pos) = gmm_model.avg_log_p(mat_features);
    likelihood_label (pos) = act_tr;
    pos++;
  }
}
  
  likelihood_actions.col(0) = likelihood_actions_scenes;
  likelihood_actions.col(1) = likelihood_label;
  
  //likelihood_actions.print();
  //cout << "Done. Press a key" << endl;
  //getchar();
  return likelihood_actions;
  
}
